package com.longrise.android.loaddata;

import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;
import android.util.Log;

import com.longrise.LEAP.Base.IO.JSONSerializer;
import com.longrise.LEAP.Base.Objects.EntityBean;
import com.longrise.LEAP.Base.Objects.ResultSetMetaData;
import com.longrise.android.util.IntenetUtil;
import com.longrise.android.util.PreferenceUtils;

import org.apache.http.HttpResponse;

import java.io.File;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

public class LoadDataManager {

    private static final String TAG = "LoadDataManager111";

    private final String APP_VERSION = "LoadDataManager_APP_VERSION";

    private final String APP_COOKIE = "LoadDataManager_APP_COOKIE";

    private String Cookie = null;

    //获取Cookie的服务参数对象
    private RequsetInfo requsetInfo = null;
    //上下文
    private Context context = null;

    private static LoadDataManager loadDataManager = null;
    //下载器列表
    private List<LoadFileRunnable> taskList;
    //userflag
    private String userflag;
    //SP名称
    public static final String SP_NAME = "LoadDownInfo";

    private String mAppVersion;

    private Map<String, Integer> mRepeatMap = new Hashtable<String, Integer>();

 //-------xkj 用于统计session过期导致登录的次数--统计完了删掉-----
    private String mUserId ;

    public void setmUserId(String mUserId) {
        this.mUserId = mUserId;
    }
//----------------------------------------------------------

    public LoadDataManager(Context context) {
        taskList = new ArrayList<LoadFileRunnable>();
        this.context = context;
        userflag = "default";
    }

    public static LoadDataManager getInstance(Context context) {
        if (null == loadDataManager) {
            synchronized (LoadDataManager.class) {
                if (null == loadDataManager && context!=null) {
                    loadDataManager = new LoadDataManager(context.getApplicationContext());
                }
            }
        }
        return loadDataManager;
    }


    //====================set()/get()=======================
    public void setAppVersion(String appVersion) {
        this.mAppVersion = appVersion;
        CacheUtils.setString(context, APP_VERSION, appVersion);
    }

    public String getAppVersion() {
        return TextUtils.isEmpty(mAppVersion) ? CacheUtils.getString(context, APP_VERSION, "24") : mAppVersion;
    }

    public List<LoadFileRunnable> getTaskList() {
        return taskList;
    }

    public String getCookie() {
        return TextUtils.isEmpty(Cookie)?CacheUtils.getString(context,APP_COOKIE):Cookie;
    }

    /**
     * 设置cookie
     *
     * @param cookie
     */
    public void setCookie(String cookie) {
        Cookie = cookie;
        CacheUtils.setString(context,APP_COOKIE,cookie);
    }

    /**
     * 设置超时请求信息
     *
     * @param requsetInfo
     */
    public void setRequsetInfo(RequsetInfo requsetInfo) {
        this.requsetInfo = requsetInfo;
    }

    /**
     * 设置上下文
     *
     * @param context
     */
    public void setContext(Context context) {
        this.context = context.getApplicationContext();
    }

    public Context getContext() {
        return context;
    }

    /**
     * 设置userflag
     *
     * @param userflag
     */
    public void setUserflag(String userflag) {
        this.userflag = userflag;
    }


    /**
     * 请求服务方法
     *
     * @param sendType
     * @param url
     * @param serviceName
     * @param map
     * @param isCache
     * @param callBack
     */
    public void callService(int sendType, String url, String serviceName, Map<String, String> map, boolean isCache, ObserverCallBack callBack) {
        if (sendType == AnsynHttpRequest.GET) {
            AnsynHttpRequest.requestByGet(context, getAppVersion(), url, serviceName, map, isCache, callBack);
        } else if (sendType == AnsynHttpRequest.POST) {
            AnsynHttpRequest.requestByPost(context, getAppVersion(), url, serviceName, map, isCache, callBack);
        }
    }

    /**
     * 请求服务方法，为了兼容原来Xutil
     *
     * @param key
     * @param serviceUrl
     * @param serviceName
     * @param bean
     * @param onRequestCallListener
     */
    public void callService(final String key, final String serviceUrl, final String serviceName, final EntityBean bean, final OnRequestCallListener onRequestCallListener) {

        if (!isNetWorkEnable(context)) { //判断网络是否可用
            Intent intent = new Intent("nonetwork");
            context.sendBroadcast(intent);
//            onRequestCallListener.onError(null, serviceName, null, false);
            onRequestCallListener.onFinished(key, serviceUrl);
            return;
        }

        if (null != context) {
            if (IntenetUtil.getNetworkState(context) == IntenetUtil.NETWORN_NONE) {
                if (null != onRequestCallListener) {
                    onRequestCallListener.onError(key, serviceName, null, false);
                    onRequestCallListener.onFinished(key, serviceName);
                }
                return;
            }
        }

        Map<String, String> map = null;
        if (bean != null) {
            ResultSetMetaData[] keys = bean.toResultSet().getMetaData();
            if (null != keys) {
                map = new HashMap<String, String>();
                for (int i = 0; i < keys.length; i++) {
                    String beanKey = keys[i].getName();
                    String value = null;
                    Object object = bean.get(beanKey);
                    //将所有的类型全部转换成String类型
                    if (object != null) {
                        if ((object instanceof String)) {
                            value = object.toString();
                        } else if ((object instanceof Integer)) {
                            value = String.valueOf(object);
                        } else if ((object instanceof Long)) {
                            value = String.valueOf(object);
                        } else if ((object instanceof Number)) {
                            value = String.valueOf(object);
                        } else if ((object instanceof Boolean)) {
                            value = String.valueOf(object);
                        } else if ((object instanceof BigDecimal)) {
                            value = String.valueOf(object);
                        } else {
                            value = JSONSerializer.getInstance().Serialize(object);
                        }
                    }

                    map.put(beanKey, value);
                    object = null;
                    value = null;
                }
            }
        }
        AnsynHttpRequest.requestByPost(context, getAppVersion(), serviceUrl, serviceName, map, false, new ObserverCallBack() {

            @Override
            public void back(String data, String url, HttpResponse httpResponse, Runnable runnable) {

            }

            @Override
            public void back(String data, String url, HttpResponse httpResponse) {

                if (null != onRequestCallListener) {
                    if (null == data || "".equals(data)) {
                        if (requsetInfo == null) {

                            String cookieBean = CacheUtils.getString(context, "cookieBean");
                            requsetInfo = (RequsetInfo) JSONSerializer.getInstance().DeSerialize(cookieBean, RequsetInfo.class);
                            mAppVersion = CacheUtils.getString(context, "AppVersion");
                        }

                        //防止服务器返回空的时候循环调用登录
                        int repeatTimes = 0;
                        if (mRepeatMap.containsKey(serviceName)) {
                            repeatTimes = mRepeatMap.get(serviceName);
                        }

                        //判断是否session过期
                        if (requsetInfo != null && httpResponse != null && repeatTimes < 3) {

                            //-----给后台上传日志---
                            uploadDailyRecord(serviceName);
                            //--------------------
                            repeatTimes++;
                            mRepeatMap.put(serviceName, repeatTimes);
                            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                                getCookIdService(key, serviceUrl, serviceName, bean, onRequestCallListener);
                                return;
                            }
                        }

                        onRequestCallListener.onError(null, serviceName, null, false);
                    } else {
                        if (mRepeatMap.containsKey(serviceName)) {
                            mRepeatMap.remove(serviceName);
                        }
                        //序列化成Bean对象
                        EntityBean bean = (EntityBean) JSONSerializer.getInstance().DeSerialize(data, EntityBean.class);
                        onRequestCallListener.onSuccess(null, serviceName, bean);
                    }
                    onRequestCallListener.onFinished(key, serviceName);
                }
            }
        });
    }

    /**
     * 请求服务方法，为了兼容原来Xutil
     *
     * @param key
     * @param serviceUrl
     * @param serviceName
     * @param bean
     * @param onRequestCallListener
     */
    private void getCookIdService(final String key, final String serviceUrl, final String serviceName, final EntityBean bean, final OnRequestCallListener onRequestCallListener) {
        Map<String, String> map = null;
        //requestInfo如果为空的话就从本地取
//        if(requsetInfo==null){
//            String cookieBean = PreferenceUtils.getPrefString("bbt", Context.MODE_PRIVATE, context,
//                    "cookieBean", null);
//            RequsetInfo requsetInfo = (RequsetInfo) JSONSerializer.getInstance().DeSerialize(cookieBean, RequsetInfo.class);
//            this.requsetInfo = requsetInfo;
//        }
        if (bean != null && requsetInfo != null) {
            ResultSetMetaData[] keys = this.requsetInfo.getBean().toResultSet().getMetaData();
            if (null != keys) {
                map = new HashMap<String, String>();
                for (int i = 0; i < keys.length; i++) {
                    String beanKey = keys[i].getName();
                    String value = null;
                    Object object = this.requsetInfo.getBean().get(beanKey);
                    //将所有的类型全部转换成String类型
                    if (object != null) {
                        if ((object instanceof String)) {
                            value = object.toString();
                        } else if ((object instanceof Integer)) {
                            value = String.valueOf(object);
                        } else if ((object instanceof Long)) {
                            value = String.valueOf(object);
                        } else if ((object instanceof Number)) {
                            value = String.valueOf(object);
                        } else if ((object instanceof Boolean)) {
                            value = String.valueOf(object);
                        } else if ((object instanceof BigDecimal)) {
                            value = String.valueOf(object);
                        } else {
                            value = JSONSerializer.getInstance().Serialize(object);
                        }
                    }

                    map.put(beanKey, value);
                    object = null;
                    value = null;
                }
            }
        }

        AnsynHttpRequest.requestByPost(context, getAppVersion(), this.requsetInfo.getServiceUrl(), this.requsetInfo.getServiceName(), map, false, new ObserverCallBack() {

            @Override
            public void back(String data, String url, HttpResponse httpResponse, Runnable runnable) {

            }

            @Override
            public void back(String data, String url, HttpResponse httpResponse) {
                //发送广播
                Intent intent = new Intent("com.longrise.loginForCookId");
                intent.putExtra("data", data);
                if (null != context) {
                    context.sendBroadcast(intent);
                }

                if (null == data || "".equals(data)) {
                    //回调接口
                    if (null != onRequestCallListener) {
                        onRequestCallListener.onSuccess(null, serviceName, null);
                        onRequestCallListener.onFinished(key, serviceName);
                    }
                } else {

                    //重新请求当前服务
                    callService(key, serviceUrl, serviceName, bean, onRequestCallListener);
                }
            }
        });
    }


    public interface OnRequestCallListener {
        public void onSuccess(String key, String service, Object result);

        public void onError(String key, String service, Throwable ex, boolean isOnCallback);

        public void onFinished(String key, String service);
    }


    /**
     * 网络是否可用
     */
    public boolean isNetWorkEnable(Context cxt) {
        ConnectivityManager connectivity = (ConnectivityManager) cxt.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity == null) {
        } else {
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null) {
                for (int i = 0; i < info.length; i++) {
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        }
        return false;
    }


    //======================================文件下载新方法============================================


    /**
     * 下载方法
     *
     * @param urlString              完整下载地址
     * @param catchPath              文件缓存名称，如：demo.mp4
     * @param onDownLoadFileListener 回调接口
     */
    public LoadFileRunnable downLoadFile(String urlString, String catchPath, OnDownLoadFileListener onDownLoadFileListener) {
        if (null == urlString || "".equals(urlString) || catchPath == null || "".equals(catchPath)) {

            return null;
        }

        LoadFileRunnable loadFileRunnable = null;

        //判断下载是否已经存在
        if (null != this.taskList) {
            for (int i = 0; i < taskList.size(); i++) {
                LoadFileRunnable temploadFileRunnable = this.taskList.get(i);
                if (null != temploadFileRunnable) {
                    String tempStr = userflag + "_mark_" + urlString;
                    if (tempStr.equals(userflag + "_mark_" + temploadFileRunnable.getUrl())) {
                        //设置接口
                        temploadFileRunnable.setOnDownLoadFileListener(onDownLoadFileListener);
                        // 禁止重复下载
                        if (temploadFileRunnable.getNowDownLoad()) {
                            return temploadFileRunnable;
                        }
                        loadFileRunnable = temploadFileRunnable;
                        loadFileRunnable.setNowDownLoad(true);
                        break;
                    }
                    tempStr = null;
                }
                temploadFileRunnable = null;
            }
        }


        if (null == loadFileRunnable) {
            loadFileRunnable = new LoadFileRunnable(context, urlString, catchPath, onDownLoadFileListener);
            loadFileRunnable.setNowDownLoad(true);
            loadFileRunnable.setUserflag(userflag);
            loadFileRunnable.setCatchPath(catchPath);
            //加入数组中
            if (null != taskList) {
                taskList.add(loadFileRunnable);
            }
        }

        // 请求
        //ThreadPoolUtils.execute(loadFileRunnable);
        // 请求
        LoadDataThreadPool.execute(loadFileRunnable);

        return loadFileRunnable;
    }

    /**
     * 删除下载任务
     *
     * @param downPath 完整下载地址
     */
    public void delTaskForPath(String downPath, final OnStopTaskListener onStopTaskListener) {
        if (null == taskList || null == downPath) {
            if (null != onStopTaskListener) {
                onStopTaskListener.onStopTask(null, false);
            }
            return;
        }

        final String tempStr = userflag + "_mark_" + downPath;

        LoadFileRunnable tempLoadFileRunnable = null;
        for (int i = 0; i < taskList.size(); i++) {
            tempLoadFileRunnable = taskList.get(i);
            if (null != tempLoadFileRunnable) {

                if (tempStr.equals(userflag + "_mark_" + tempLoadFileRunnable.getUrl())) {
                    break;
                }
            }
        }


        if (null != tempLoadFileRunnable) {

            //判断任务是否已经停止
            if (tempLoadFileRunnable.getNowDownLoad()) {
                PrintLog.d(TAG, "AAAA");
                //停止任务
                tempLoadFileRunnable.stopTask(false, new OnStopTaskListener() {
                    @Override
                    public void onStopTask(LoadFileRunnable loadFileRunnable, boolean b) {
                        PrintLog.d(TAG, "BBB:" + b);
                        //从线程池中移除
                        //ThreadPoolUtils.remove(loadFileRunnable);
                        LoadDataThreadPool.remove(loadFileRunnable);
                        //集合中移除
                        taskList.remove(loadFileRunnable);
                        delFile(tempStr, loadFileRunnable, onStopTaskListener);
                    }
                });
            } else {
                //从线程池中移除
                //ThreadPoolUtils.remove(tempLoadFileRunnable);
                LoadDataThreadPool.remove(tempLoadFileRunnable);
                //集合中移除
                taskList.remove(tempLoadFileRunnable);
                delFile(tempStr, tempLoadFileRunnable, onStopTaskListener);
            }


        } else {
            delFile(tempStr, tempLoadFileRunnable, onStopTaskListener);
        }


    }

    private void delFile(String tempStr, LoadFileRunnable myloadFileRunnable, OnStopTaskListener onStopTaskListener) {
        String value = PreferenceUtils.getPrefString(SP_NAME, context.MODE_PRIVATE, context, tempStr, null);
        EntityBean bean = (EntityBean) JSONSerializer.getInstance().DeSerialize(value, EntityBean.class);

        if (null == bean) {
            onStopTaskListener.onStopTask(myloadFileRunnable, false);
            return;
        }
        //删除文件
        String localFilePath = bean.getString("localpath", null);

        if (null != localFilePath) {
            File tempFile = new File(localFilePath);
            if (tempFile.exists()) {
                if (!tempFile.delete()) {
                    if (null != onStopTaskListener) {
                        onStopTaskListener.onStopTask(myloadFileRunnable, false);
                    }
                    return;
                }
            }
        }

        //置空Plist里的信息
        PreferenceUtils.setPrefString(SP_NAME, context.MODE_PRIVATE, context, tempStr, null);

        if (null != onStopTaskListener) {
            onStopTaskListener.onStopTask(myloadFileRunnable, true);
        }
    }

    /**
     * 暂停任务
     *
     * @param downPath
     */
    public boolean stopTaskForDownPath(String downPath) {
        if (null == downPath || "".equals(downPath)) {
            return false;
        }

        if (null == taskList) {
            return false;
        }
        for (int i = 0; i < taskList.size(); i++) {
            LoadFileRunnable tempLoadFileRunnable = taskList.get(i);
            if (null != tempLoadFileRunnable) {
                String tempStr = userflag + "_mark_" + downPath;
                if (tempStr.equals(userflag + "_mark_" + tempLoadFileRunnable.getUrl())) {
                    tempLoadFileRunnable.setNowDownLoad(false);
                    return true;
                }
                tempStr = null;
            }
            tempLoadFileRunnable = null;
        }
        return false;
    }

    /**
     * 根据下载路径获取下载信息
     *
     * @param downPath
     * @return
     */
    public EntityBean getDownInfoForDownPath(String downPath) {
        //拼接路径
        String key = userflag + "_mark_" + downPath;
        String value = PreferenceUtils.getPrefString(SP_NAME, context.MODE_PRIVATE, context, key, null);
        Log.e("==========>value", value + "");
        EntityBean bean = (EntityBean) JSONSerializer.getInstance().DeSerialize(value, EntityBean.class);
        return bean;
    }

    /**
     * 根据下载路径判断任务是否正在下载
     *
     * @param downPath
     */
    public boolean isDownLoadForDownPath(String downPath) {
        if (null == downPath || "".equals(downPath)) {
            return false;
        }

        if (null == taskList) {
            return false;
        }
        for (int i = 0; i < taskList.size(); i++) {
            LoadFileRunnable tempLoadFileRunnable = taskList.get(i);
            if (null != tempLoadFileRunnable) {
                String tempStr = userflag + "_mark_" + downPath;
                if (tempStr.equals(userflag + "_mark_" + tempLoadFileRunnable.getUrl())) {
                    return tempLoadFileRunnable.getNowDownLoad();
                }
                tempStr = null;
            }
            tempLoadFileRunnable = null;
        }

        return false;

    }

    /**
     *
     */
    public void onDestory() {
        if (taskList != null) {
            for (int i = 0; i < taskList.size(); i++) {
                LoadFileRunnable loadFileRunnable = taskList.get(i);
                if (loadFileRunnable != null) {
                    loadFileRunnable.setNowDownLoad(false);
                    //LoadDataThreadPool.remove(loadFileRunnable);
                }
            }
        }
        loadDataManager = null;
    }

    /**
     * xkj 20170328给后台上传日志 以后删掉
     */
    private void uploadDailyRecord(final String serviceName){
         new Thread(){
             @Override
             public void run() {
                 try {
                     URL url = new URL("http://59.173.241.186:8042/BBT/restservices/bbapp/bbt_setapplogs/query");
                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                     conn.setRequestMethod("POST");
                     conn.setConnectTimeout(10*1000);

                     EntityBean bean = new EntityBean();
                     bean.set("comfrom","android");
                     bean.set("logs",mUserId);
                     bean.set("serviceName",serviceName);
                     String serialize = JSONSerializer.getInstance().Serialize(bean);
                     String data = "bean="+ URLEncoder.encode(serialize,"UTF-8");

                     conn.setRequestProperty("Connection", "keep-alive");
                     conn.setRequestProperty("Content-Type",
                             "application/x-www-form-urlencoded");
                     conn.setRequestProperty("Content-Length",
                             String.valueOf(data.getBytes().length));

                     conn.setDoOutput(true); // 发送POST请求必须设置允许输出
                     conn.setDoInput(true);
                     OutputStream os = conn.getOutputStream();
                     os.write(data.getBytes());
                     os.flush();
                     int statusCode = conn.getResponseCode();
                     conn.disconnect();
                     os.close();
                 } catch (Exception e){

                 }
             }
         }.start();
    }

}
